package com.hui.platform.falseworkapi.common.web;

import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.serializer.ValueFilter;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * WEB MVC 配置
 * @author Peng
 * @date 2019/11/4
 */
@Configuration
public class WebMvcGlobalConfig implements WebMvcConfigurer {

    /**
     * 设置全局跨域
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry
                // 设置允许跨域的路径
                .addMapping("/**")
                // 设置允许跨域请求的域名
                .allowedOrigins("*")
                // 是否允许证书 不再默认开启
                .allowCredentials(true)
                // 设置允许的方法
                .allowedMethods("*")
                // 跨域允许时间
                .maxAge(3600);
    }

    /**
     * 配置fastJSON消息转换器
     *
     * @param converters 转换器集
     */
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
        //配置转换器
        FastJsonHttpMessageConverter converter = new CustomFastJsonHttpMessageConverter();

        //配置支持类型
        List<MediaType> supportedMediaTypes = new ArrayList<>();
        supportedMediaTypes.add(MediaType.APPLICATION_JSON);
        supportedMediaTypes.add(MediaType.APPLICATION_ATOM_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_FORM_URLENCODED);
        supportedMediaTypes.add(MediaType.APPLICATION_OCTET_STREAM);
        supportedMediaTypes.add(MediaType.APPLICATION_PDF);
        supportedMediaTypes.add(MediaType.APPLICATION_RSS_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XHTML_XML);
        supportedMediaTypes.add(MediaType.APPLICATION_XML);
        supportedMediaTypes.add(MediaType.IMAGE_GIF);
        supportedMediaTypes.add(MediaType.IMAGE_JPEG);
        supportedMediaTypes.add(MediaType.IMAGE_PNG);
        supportedMediaTypes.add(MediaType.TEXT_EVENT_STREAM);
        supportedMediaTypes.add(MediaType.TEXT_HTML);
        supportedMediaTypes.add(MediaType.TEXT_MARKDOWN);
        supportedMediaTypes.add(MediaType.TEXT_PLAIN);
        supportedMediaTypes.add(MediaType.TEXT_XML);
        //设置类型
        converter.setSupportedMediaTypes(supportedMediaTypes);

        //fastJson配置
        FastJsonConfig fastJsonConfig = new FastJsonConfig();

        //序列化特征
        fastJsonConfig.setSerializerFeatures(
                // List字段如果为null,输出为[],而非null
                SerializerFeature.WriteNullListAsEmpty,
                //加上后，字段为null的也会输出
                SerializerFeature.WriteMapNullValue,
                //字符类型字段如果为null,输出为"",而非null
                SerializerFeature.WriteNullStringAsEmpty,
                //消除对同一对象循环引用的问题，默认为false（如果不配置有可能会进入死循环）
                SerializerFeature.DisableCircularReferenceDetect,
                //结果是否格式化,默认为false
                SerializerFeature.PrettyFormat,
                //新增------------------------------
                //Boolean字段如果为null,输出为false,而非null
                SerializerFeature.WriteNullBooleanAsFalse,
                //处理Long太长导致js精度丢失的问题
                SerializerFeature.BrowserCompatible
        );

        //添加格式化器（自定义）
        fastJsonConfig.setSerializeFilters(new BigDecimalValueFilter(), new LongValueFilter());

        //日期格式化
        //fastJsonConfig.setDateFormat("yyyy-MM-dd HH:mm:ss")
        converter.setFastJsonConfig(fastJsonConfig);

        //返回是string的话，默认把这个放在最前，否则ResponseBodyAdvice 处理字符串返回时会报类型不一致的问题
        converters.add(0, converter);
    }


    //------------------私有区---------------------------------


    /**
     * 拓展FastJsonHttpMessageConverter
     */
    private static class CustomFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
        /**
         * 是否支持此类的格式转换（包括读写）
         *
         * @param clazz 需要转换的Class对象
         * @return 是否支持
         */
        @Override
        protected boolean supports(Class<?> clazz) {
            /*
             *  不支持处理Oauth框架的结果
             *  相关转换处理器:
             *  MappingJackson2HttpMessageConverter
             *  FormOAuth2AccessTokenMessageConverter
             *  FormOAuth2ExceptionHttpMessageConverter
             *  处理方法：返回不支持策略
             *  OAuth2AccessToken.class.isAssignableFrom(clazz)
             *  OAuth2Exception.class.isAssignableFrom(clazz)
             */
            return super.supports(clazz);
        }
    }


    // 添加转换器把BigDecimal值转化成字符串输出
    private class BigDecimalValueFilter implements ValueFilter {
        @Override
        public Object process(Object object, String name, Object value) {
            if (value instanceof BigDecimal) {
                return String.format("%.2f", ((BigDecimal) value).doubleValue());
            }
            return value;
        }
    }

    // Id转字符串
    private class LongValueFilter implements ValueFilter {
        @Override
        public Object process(Object object, String name, Object value) {
            boolean flag = (name.toLowerCase().contains("id"));
            if (value instanceof Long && flag) {
                return value.toString();
            }
            return value;
        }
    }

}


